package com.api.chatai.service.Impl;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.RandomUtil;
import com.api.chatai.domain.dtos.LoginDto;
import com.api.chatai.domain.dtos.RegisterDto;
import com.api.chatai.domain.pojo.Goods;
import com.api.chatai.domain.pojo.User;
import com.api.chatai.exception.myException;
import com.api.chatai.mapper.UserMapper;
import com.api.chatai.service.GoodsService;
import com.api.chatai.service.UserService;
import com.api.chatai.utils.JwtHelper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 *
 */
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Autowired
    private  StringRedisTemplate redisTemplate;
    @Autowired
    private  JavaMailSender javaMailSender;
    @Autowired
    private GoodsService goodsService;

    /*
     * 用户登录
     */
    @Override
    public String login(LoginDto loginDto) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getEmail, loginDto.getEmail());
        User one = getOne(wrapper);
        if (one == null) {
            throw new myException("该邮箱尚未注册");
        }
        if (!BCrypt.checkpw(loginDto.getPassword(), one.getPassword())) {
            throw new myException("密码错误");
        }
        return JwtHelper.createToken(one.getId());

    }


    /*
     * 用户注册
     */
    @Override
    public String register(RegisterDto registerDto) {
        //检验邮箱格式
        if (!Validator.isEmail(registerDto.getEmail())) {
            throw new myException("邮箱格式错误");
        }

        //检验邮箱是否已注册
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getEmail, registerDto.getEmail());
        if (getOne(wrapper) != null) {
            throw new myException("该邮箱已注册");
        }

        //密码6-20位
        if (registerDto.getPassword().length() < 6 || registerDto.getPassword().length() > 20) {
            throw new myException("请设置6-20位的密码");
        }

        //检验验证码
        String code = redisTemplate.opsForValue().get("emailCodes:" + registerDto.getEmail());
        if (!registerDto.getCode().equals(code)) {
            throw new myException("验证码错误");
        }

        //密码加密 保存用户
        User user = new User();
        user.setEmail(registerDto.getEmail());
        user.setPassword(BCrypt.hashpw(registerDto.getPassword(), BCrypt.gensalt()));
        user.setToken(10000L);
        boolean saved = save(user);
        if (!saved) {
            throw new myException("注册失败");
        }
        String token = JwtHelper.createToken(user.getId());
        return token;
    }

    /*
    发送邮箱验证码
     */
    @Override
    public void sendCode(String email) {
        //检验邮箱格式
        if (!Validator.isEmail(email)) {
            throw new myException("邮箱格式错误");
        }

        //检验邮箱是否已注册
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getEmail, email);
        if (getOne(wrapper) != null) {
            throw new myException("该邮箱已注册");
        }

        //生成验证码
        String code = RandomUtil.randomNumbers(6);
        //存入redis
        Boolean absent = redisTemplate.opsForValue().setIfAbsent("emailCodes:" + email, code, 2, TimeUnit.MINUTES);
        if (absent == null) {
            throw new myException("系统异常,请稍后再试");
        }
        if (!absent) {
            throw new myException("该邮箱2分钟内已发送验证码,请稍后再试");
        }
        sendMail(email, code);
    }

    /*
     * 添加token
     */
    @Override
    public void addToken(Long userId, Long goodsId) {
        User user = getById(userId);
        Goods goods = goodsService.getById(goodsId);
        user.setToken(user.getToken() + goods.getToken());
        System.out.println(user);
        updateById(user);
    }


    public void sendMail(String targetEmail, String code) {
        String from = "bwovr33655@163.com";
        String subject = "验证码";
        String text = "Chatai注册验证码 : " + code + "  (2分种内有效)";
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(from + "(Chatai)");
        message.setTo(targetEmail);
        message.setSubject(subject);
        message.setText(text);
        javaMailSender.send(message);
    }


}